package com.yyf.camera_product_plugin.camera_product_plugin

import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter
import android.content.Context
import android.graphics.Bitmap
import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.util.Log
import cn.com.heaton.blelibrary.DevManager
import cn.com.heaton.blelibrary.ble.BleStates
import cn.com.heaton.blelibrary.ble.model.BleDevice
import cn.com.heaton.blelibrary.bluemanager.BlueManager
import cn.com.heaton.blelibrary.bluemanager.bean.WifiInfo
import cn.com.heaton.blelibrary.bluemanager.callback.ConnectBlueDelegate
import cn.com.heaton.blelibrary.bluemanager.callback.ScanBlueDelegate
import com.example.i4seasoncameralib.cameramanager.CameraManager
import com.example.i4seasoncameralib.cameramanager.handler.CameraConstant
import com.example.i4seasoncameralib.cameramanager.handler.CameraEventObserver
//import com.example.i4seasoncameralib.cameramanager.handler.CameraEventObserver.OfflineListener
//import com.example.i4seasoncameralib.cameramanager.handler.CameraEventObserver.OnAcceptBitmapListener
//import com.example.i4seasoncameralib.cameramanager.handler.CameraEventObserver.OnKeyPhotoOrRecoderListener
//import com.example.i4seasoncameralib.cameramanager.handler.CameraEventObserver.OnKeyZoomListener
//import com.example.i4seasoncameralib.cameramanager.handler.CameraEventObserver.OnResolutionListListener
//import com.example.i4seasoncameralib.cameramanager.handler.CameraEventObserver.OnTakePhotoOrRecoderListener
import com.google.gson.Gson
import com.jni.WifiCameraInfo.WifiCameraParameter
import com.jni.WifiCameraInfo.WifiCameraResolution
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.EventChannel.EventSink
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import java.io.ByteArrayOutputStream
import java.io.File
import java.util.concurrent.Executors

import cn.com.heaton.blelibrary.bluemanager.callback.ICommandCallBack


/** CameraProductPlugin */
class CameraProductPlugin : FlutterPlugin, MethodCallHandler,
    EventChannel.StreamHandler, CameraEventObserver.OnAcceptBitmapListener,
    CameraEventObserver.OfflineListener, CameraEventObserver.OnTakePhotoOrRecoderListener,
    CameraEventObserver.OnKeyPhotoOrRecoderListener,
    CameraEventObserver.OnKeyZoomListener,
    CameraEventObserver.OnResolutionListListener {
    /// The MethodChannel that will the communication between Flutter and native Android
    ///
    /// This local reference serves to register the plugin with the Flutter Engine and unregister it
    /// when the Flutter Engine is detached from the Activity

    private val methodChannelName = "camera_product_plugin"
    private val eventChannelName = "camera_product_plugin_event"

    private val TAG: String = "【插件】"
    var fileName: String = ""//拍照文件名


    private lateinit var channel: MethodChannel
    private lateinit var eventChannel: EventChannel

    // 定义一个上下文
//    private var activity: Activity? = null
    private lateinit var context: Context
    private lateinit var eventSink: EventSink
    private lateinit var handler: Handler


    //例 保存到DCIM   该路径可自行选择更改 注意权限问题即可
    private lateinit var savePath: String
    private var mCurrentBitmap: Bitmap? = null


    override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        context = flutterPluginBinding.applicationContext
        savePath = context.getExternalFilesDir(null)?.absolutePath + File.separator + Environment.DIRECTORY_DCIM + File.separator + "/WifiCameraDemo"

        handler = Handler(Looper.getMainLooper())

        channel = MethodChannel(flutterPluginBinding.binaryMessenger, methodChannelName)
        channel.setMethodCallHandler(this)


        // eventChannel
        eventChannel = EventChannel(flutterPluginBinding.binaryMessenger, eventChannelName)
        eventChannel.setStreamHandler(this)


        //初始化功能
//        initData(context)
    }

    override fun onListen(arguments: Any?, events: EventSink) {
        eventSink = events

    }

    override fun onCancel(arguments: Any?) {

    }

    override fun onMethodCall(call: MethodCall, result: Result) {
        val method = call.method
        val arguments = call.arguments
        println("debug000 ===  ${call.method}");
        if (call.method == "initCameraSDK") {//进入拍照页面，初始化相机
            initCameraSDK()
        } else if (call.method == "getPlatformVersion") {
            result.success("Android ${android.os.Build.VERSION.RELEASE}")
        } else if (call.method == "scanBluetooth") {//扫描蓝牙
            BlueManager.getInstance().init(context)//初始化蓝牙库
            var time = 30
            if (arguments != null) {
                arguments as Map<String, Any>
                if (arguments.containsKey("time")) {
                    time = (arguments.containsKey("time") as Number).toInt()
                }
            }
            startScanDeviceList(time)
            result.success("scanBluetooth  success ")
        } else if (call.method == "connectBluetooth") {//连接蓝牙
            println("连接设备 参数 ===  $arguments")
            //{param={"isAutoConnecting":false,
            // "mAutoConnect":false,
            // "mBleAddress":"7C:3E:82:F6:C8:48",
            // "mBleName":"IPC7c3e82f6c847",
            // "mConnectionState":0,
            // "mDeviceType":2,"mRssi":-33,
            // "scanRecord":{"mAdvertiseFlags":6,"mBytes":[2,1,6,7,-1,66,76,54,49,54,0,16,9,73,80,67,55,99,51,101,56,50,102,54,99,56,52,55,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            // "mDeviceName":"IPC7c3e82f6c847","mManufacturerSpecificData":{},"mServiceData":{},"mTxPowerLevel":-2147483648}}}
            if (arguments != null) {
                val paramMap = arguments as Map<*, *>
                val paramValue = paramMap["param"]
                val bleDevice: BleDevice =
                    Gson().fromJson(paramValue.toString(), BleDevice::class.java)
                connectBlue(bleDevice);
            }
            result.success("connectBluetooth  success ")
        } else if (call.method == "scanWIFI") {//扫描WIFI
            println("调用扫描WIFI方法")
            startScanWIFIList()
            result.success("scanWIFI  success ")
        } else if (call.method == "connectWIFI") {//连接WIFI
            println("调用连接WIFI方法")
            if (arguments != null) {
                val paramMap = arguments as Map<*, *>
                val paramValue = paramMap["param"]
                val wifiInfo: WifiInfo =
                    Gson().fromJson(paramValue.toString(), WifiInfo::class.java)
                connectWIFI(wifiInfo);
            }

            result.success("connectWIFI  success ")
        } else if (call.method == "takePhoto") {//拍照
            takePhoto()
            result.success("takePhoto  success ")
        } else if (call.method == "removeCameraListener") {//移除相机监听事件
            removeCameraListener()
            result.success("removeCameraListener  success ")
        } else if (call.method == "disConnectBluetooth") {//断开蓝牙设备
            disConnectBluetooth()
            result.success("disConnectBluetooth  success ")
        } else if (call.method == "getCurrentDeviceName") {//获取当前已链接设备的名字
            getCurrentDeviceName()
            result.success("getCurrentDeviceName  success ")
        } else if (call.method == "getCurrentDeviceWifiSSID") {//获取当前已链接设备的wifi名字
            getCurrentDeviceWifiSSID()
            result.success("getCurrentDeviceWifiSSID  success ")
        } else if (call.method == "getCurrentDeviceWifiSatate") {//获取当前已链接设备的wifi状态
            getCurrentDeviceWifiSatate()
            result.success("getCurrentDeviceWifiSatate  success ")
        } else {
            result.notImplemented()
        }
    }

    override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
        eventChannel.setStreamHandler(null)
    }

    //==========================以下为插件功能=================================


    //扫描设备
    @SuppressLint("MissingPermission")
    fun startScanDeviceList(time: Int) {

        //判断蓝牙是否开启
        val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
        if (bluetoothAdapter != null && !bluetoothAdapter.isEnabled) {
            val result = bluetoothAdapter.enable()
            //bluetoothAdapter.enable() 在33上被弃用  默认返回false  这里做一个兼容
//            if (!result && Build.VERSION.SDK_INT >= 33) {
//                val blueIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
//                startActivityForResult(blueIntent, 10085)
//            }
            return
        }

        BlueManager.getInstance().stopScanBlue() //cacel

        //            BlueManager.getInstance().isScanning();//isScanning
        BlueManager.getInstance().scanAllBlue("IPC", 10000, object : ScanBlueDelegate {
            //start
            override fun scanBlueNotice(bleDevices: List<BleDevice>, bleDevice: BleDevice) {
                println("扫描到设备 === $bleDevice")

//                BleDevice{mConnectionState=0,
//                mBleAddress='7C:3E:82:F6:C8:48',
//                mBleName='IPC7c3e82f6c847',
//                mBleAlias='null', mRssi=-29,
//                mDeviceType=2, mAutoConnect=false,
//                isAutoConnecting=false,
//                scanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=null, mManufacturerSpecificData={19522=[54, 49, 54, 0]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=IPC7c3e82f6c847], mPropertyMap=null}

                handler.post {
                    val map = HashMap<String, Any>()
                    map.put("find_new_device", Gson().toJson(bleDevice))
                    eventSink.success(map)
                }
            }

            override fun scanBlueDelegate(bleDevice: BleDevice) {
            }

            override fun ScanStart() {
                println("扫描设备 === ScanStart")
            }

            override fun ScanStop(bleDevices: List<BleDevice>) {
                println("扫描设备 === ScanStop")
                handler.post {
                    val map = HashMap<String, Any>()
                    map.put("find_new_device", "")
                    eventSink.success(map)
                }
            }

            override fun ScanCancel(bleDevices: List<BleDevice>) {
                println("扫描设备 === ScanCancel")
            }
        })
    }

    private var cConnected: BleDevice? = null

    fun connectBlue(bleDevice: BleDevice?) {
        if (cConnected != null) {
            BlueManager.getInstance().disConnectBlueDevice(cConnected)
            cConnected = null
        }
        BlueManager.getInstance().connectBlueDevice(bleDevice, object : ConnectBlueDelegate {
            override fun connectBlueNotice(bleDevice: BleDevice, errorCode: Int) {
                if (errorCode == BleStates.Successful) {
                    println("蓝牙连接成功")
                } else if (errorCode == BleStates.ConnectedAlready) {
                    println("蓝牙准备连接")
                    handler.post {
                        val map = HashMap<String, Any>()
                        map.put("connect_device_code", "100");
                        eventSink.success(map)
                    }
                } else if (errorCode == BleStates.ConnectError || errorCode == BleStates.ConnectFailed || errorCode == BleStates.ConnectTimeOut || errorCode == BleStates.ConnectException) {
                    Log.d(TAG, "蓝牙单次连接失败")
                    handler.post {
                        val map = HashMap<String, Any>()
                        map.put("connect_device_code", "300");
                        eventSink.success(map)
                    }
                } else if (errorCode == BleStates.MaxConnectNumException) {
                    Log.d(TAG, "蓝牙连接失败超过最大重试次数 ")
                    handler.post {
                        val map = HashMap<String, Any>()
                        map.put("connect_device_code", "400");
                        eventSink.success(map)
                    }
                }
            }

            override fun blueStatusChanged(bleDevice: BleDevice) {
                val connectionState = bleDevice.connectionState
                Log.d(TAG, "blue State : $connectionState")
                if (connectionState == BleDevice.DISCONNECT) {
                    Log.d(TAG, bleDevice.bleName + " 蓝牙设备已断开")
                    DevManager.getInstance().clearData()
                    cConnected = null

                    handler.post {
                        val map = HashMap<String, Any>()
                        map.put("connect_device_code", "300");
                        eventSink.success(map)
                    }
                } else if (connectionState == BleDevice.CONNECTING) {
                    Log.d(TAG, bleDevice.bleName + " 蓝牙设备连接中")
                } else if (connectionState == BleDevice.CONNECTED) {
                    Log.d(TAG, bleDevice.bleName + " 蓝牙设备已连接")
                    cConnected = bleDevice

                    handler.post {
                        val map = HashMap<String, Any>()
                        map.put("connect_device_code", "200");
                        eventSink.success(map)
                    }
                }
            }
        })
    }


    /**
     * 扫描WIFI列表
     */
    fun startScanWIFIList() {
        if (cConnected == null) {
            println("扫描WIFI返回了")
            return
        }
        println("开始扫描WIFI信息")
        DevManager.getInstance().scanWifiList(cConnected) { param1: Any?, param2: Int ->
            val wifiInfo = param1 as WifiInfo?
            println("扫描到WIFI信息")
            println(Gson().toJson(wifiInfo))
            //{
            //	"channel": 1,
            //	"encryption": 1,
            //	"isEndPackage": true,
            //	"signal": 58,
            //	"ssid": "LANJING"
            //}
            handler.post {
                val map = HashMap<String, Any>()
                map.put("find_wifi", Gson().toJson(wifiInfo))
                eventSink.success(map)
            }
        }

    }

    /**
     * 连接WIFI
     */
    fun connectWIFI(wifiInfo: WifiInfo) {
        Log.i(TAG, "发送wifi参数 ===  ${Gson().toJson(wifiInfo)}")
        //{
        //	"channel": 1,
        //	"encryption": 1,
        //	"isEndPackage": true,
        //	"password": "lanjing2022",
        //	"signal": 63,
        //	"ssid": "lanjing"
        //}
        if (cConnected == null) {
            handler.post {
                val map = HashMap<String, Any>()
                map.put("connect_wifi_code", "-1");
                eventSink.success(map)
            }
            Log.i(TAG, "连接WIFI找不到设备")
            return
        }
        DevManager.getInstance().connectWifi(cConnected, wifiInfo) { param1: Any?, param2: Int ->
            if (param2 == 0) {
                Log.i(TAG, "wifi连接成功")
                handler.post {
                    val map = HashMap<String, Any>()
                    map.put("connect_wifi_code", "200");
                    eventSink.success(map)
                }
            } else {
                handler.post {
                    val map = HashMap<String, Any>()
                    map.put("connect_wifi_code", "0");
                    eventSink.success(map)
                }
            }
        }
    }


    /**
     * 初始化摄像头SDK
     */
    fun initCameraSDK() {

        CameraManager.getInstance().initProgrammeSdk(context)

        val executor = Executors.newCachedThreadPool()
        executor.execute {


            val deviceOnlineStatus = CameraManager.getInstance().deviceOnlineStatus
            if (deviceOnlineStatus) {
                Log.d(TAG, "deviceOnlineStatus = $deviceOnlineStatus")
            }

            CameraManager.getInstance().exposureGet()

            //        获取wifi图像参数  注意获取失败会返回空
            val wifiCameraParameter = CameraManager.getInstance().cameraParameter

            //设置wif图像参数  写入要修改的参数
            val wifiCameraParameter1 = WifiCameraParameter()
            val errcode = CameraManager.getInstance().setCameraParameter(wifiCameraParameter1)
            if (errcode == 0) {
                //获取成功
            }

            //设置模式
            val modeltype = 1

            //code==0  suss
            val code = CameraManager.getInstance().setWorkModel(modeltype)

            //获取模式
            val model = CameraManager.getInstance().workModel

            //注册模式变化的监听
            CameraManager.getInstance()
                .setDeviceInfoChange { wifiCameraStatusInfo -> //workmodel有变化会在这里回调   如设备按键切换模式
                    val model = wifiCameraStatusInfo.workMode
                }


            //六轴陀螺仪监听
            CameraManager.getInstance().setGyroscope6axisListener {
                Log.d(
                    TAG,
                    "收到六轴陀螺仪数据"
                )
            }


        }
        executor.shutdown()


        CameraManager.getInstance().acceptResolutionList(this)
        CameraManager.getInstance().acceptCurrentResolution(this)
        CameraManager.getInstance()
            .resolutionSet(this, WifiCameraResolution())
        CameraManager.getInstance().setOnOfflineListener(this)
        CameraManager.getInstance().setOnAcceptBitmapListener(this)
        CameraManager.getInstance().setOnOnKeyPhotoOrRecoderListener(this)
        CameraManager.getInstance().setOnOnKeyZoomListener(this)
    }


    /**
     * 拍照
     */
    fun takePhoto() {
        println(">>> takePhoto : 进入拍照方法")
        if (mCurrentBitmap == null) {
            return
        }
        println(">>> takePhoto : 拍照启动")
        fileName = "Pic_" + System.currentTimeMillis().toString().replace(":", "_") + ".PNG"

        CameraManager.getInstance().takePhoto(
            mCurrentBitmap, savePath, fileName, this
        )
    }


    /**
     * 拍照接受图片
     */
    override fun onAcceptBitmap(bitmap: Bitmap?) {
        //注意：每一帧数据都会回调到这里
        // 所以这里不要做耗时操作
        // 且此方法在子线程内
        // 如需操作ui需要切换到主线程
        handler.post {
            Log.i(TAG, "拍照接收图片")
            mCurrentBitmap = bitmap

            val stream = ByteArrayOutputStream()
            mCurrentBitmap?.compress(Bitmap.CompressFormat.JPEG, 50, stream) // 压缩质量，可根据需要调整
            val byteArray = stream.toByteArray()

            val map = HashMap<String, Any>()
            map.put("bitmap_steam", byteArray);
            eventSink.success(map)
        }
    }


    /**
     * 设备离线回调
     */
    override fun onOfflineListener() {
        Log.d(TAG, "设备状态 设备离线")
        handler.post {
            val map = HashMap<String, Any>()
            map.put("wifi_camera_state", "offline");
            eventSink.success(map)
        }
    }

    override fun onConnectingListener() {
        Log.d(TAG, "设备状态 设备连接中")
        handler.post {
            val map = HashMap<String, Any>()
            map.put("wifi_camera_state", "connecting");
            eventSink.success(map)
        }
    }

    override fun onConnectErrorListener(p0: Int) {
        Log.d(TAG, "设备状态 连接错误:")
        handler.post {
            val map = HashMap<String, Any>()
            map.put("wifi_camera_state", "connect_error");
            map.put("wifi_camera_state_code", p0);
            eventSink.success(map)
        }
    }

    override fun onOnlineListener() {
        Log.d(TAG, "设备状态 设备上线:")
        handler.post {
            val map = HashMap<String, Any>()
            map.put("wifi_camera_state", "online");
            eventSink.success(map)
        }
    }

    override fun onUpdataDeviceListener() {

    }


    override fun onTakePhotoOrRecoderListener(p0: Boolean, p1: String?, p2: Int) {
        println(">>> takePhoto : 结果 === $p0 ,$p1 ,$p2")
        // p0  是否成功  , p1  路径  ， p2  拍照 or  录制
        handler.post {
            if (p0) {//拍照成功
                val dataMap = HashMap<String, Any>()
                dataMap.put("code", "200")
                dataMap.put("photo_path", savePath + File.separator + fileName)

                val map = HashMap<String, Any>()
                map.put("take_photo_code", Gson().toJson(dataMap))
                eventSink.success(map)
            } else {
                val dataMap = HashMap<String, Any>()
                dataMap.put("code", "300")
                dataMap.put("photo_path", "")

                val map = HashMap<String, Any>()
                map.put("take_photo_code", Gson().toJson(dataMap));
                eventSink.success(map)
            }
        }
    }

    override fun initMediaCodecFaild(p0: Int, p1: Int, p2: Int, p3: Int) {

    }

    override fun onKeyTakePhoto() {
        Log.d("TAG", "物理按键拍照")
        takePhoto()
    }

    override fun onKeyRecoderBegin() {
        Log.d("TAG", "物理按键 录制开始")
    }

    override fun onKeyRecoderEnd() {
        Log.d("TAG", "物理按键 录制结束")
    }

    override fun onKeyZoom(p0: Boolean) {
        Log.d("TAG", "物理按键 放大缩小  ")
    }

    override fun onAcceptResolutionList(p0: MutableList<WifiCameraResolution>?) {

    }

    override fun onAcceptCurrentResolution(p0: WifiCameraResolution?) {

    }

    override fun resolutionSet(p0: Boolean) {

    }

    /**
     * 移除监听
     */
    fun removeCameraListener() {
        CameraManager.getInstance().removeEventObserverListenser(
            CameraConstant.EVENT_TAKE_PHOTO_RECORDERO,
            this
        )
        CameraManager.getInstance().removeEventObserverListenser(
            CameraConstant.EVENT_BITMAP,
            this
        )
        CameraManager.getInstance().removeEventObserverListenser(
            CameraConstant.EVENT_ONLINE_OFFLINE_CHANGE,
            this
        )

        //        CameraManager.getInstance().removeEventObserverListenser(CameraConstant.EVENT_DEVICE_INFO_CHANGE, this);
        CameraManager.getInstance().removeEventObserverListenser(
            CameraConstant.EVENT_KEY_PHOTO_RECORDER,
            this
        )
        CameraManager.getInstance().removeEventObserverListenser(
            CameraConstant.EVENT_KEY_ZOOM,
            this
        )
        CameraManager.getInstance().removeEventObserverListenser(
            CameraConstant.EVENT_RESOLUTION,
            this
        )

    }

    /**
     * 断开蓝牙连接
     */
    fun disConnectBluetooth() {
        if (cConnected != null) {
            BlueManager.getInstance().disConnectBlueDevice(cConnected)
            cConnected = null
        }
    }


    /**
     * 获取当前已链接设备的名字
     */
    fun getCurrentDeviceName() {
        if (cConnected != null) {
            handler.post {
                val map = HashMap<String, Any>()
                map.put("current_device", "${cConnected!!.getBleName()}")
                eventSink.success(map)
            }
        }
    }

    /**
     * 获取当前已链接设备的wifi名字
     */
    fun getCurrentDeviceWifiSSID() {
        if (cConnected != null) {
            DevManager.getInstance().getWifiSsid(cConnected!!, object : ICommandCallBack {
                override fun callBack(name: Any, cmd: Int) {
                    if (cmd == 0) {
                        handler.post {
                            val map = HashMap<String, Any>()
                            map.put("current_device_ssid", "$name")
                            eventSink.success(map)
                        }
//                        "获取wifissid成功：" + `object`.toString()
                    }
                }
            })
        }
    }

    /**
     * 获取当前已链接设备的wifi状态
     */
    fun getCurrentDeviceWifiSatate() {
        if (cConnected != null) {
            DevManager.getInstance().getDistributionNetworkStatus(cConnected!!, object : ICommandCallBack {
                override fun callBack(state: Any, cmd: Int) {
                        if (cmd == 0) {
                            handler.post {
                                val map = HashMap<String, Any>()
                                map.put("current_device_wifi_state", "$state")
                                eventSink.success(map)
                            }
//                                if (i.toInt() == 1) {
//                                        Toast.makeText(
//                                            this@MainActivity,
//                                            "设备没有配置wifi",
//                                            Toast.LENGTH_SHORT
//                                        ).show()
//                                } else if (i.toInt() == 2) {
//                                        Toast.makeText(
//                                            this@MainActivity,
//                                            "wifi没有连接成功",
//                                            Toast.LENGTH_SHORT
//                                        ).show()
//                                } else if (i.toInt() == 3) {
//                                        Toast.makeText(
//                                            this@MainActivity,
//                                            "wifi连接成功",
//                                            Toast.LENGTH_SHORT
//                                        ).show()
//                                } else if (i.toInt() == 10) {
//                                        Toast.makeText(
//                                            this@MainActivity,
//                                            "wifi密码错误",
//                                            Toast.LENGTH_SHORT
//                                        ).show()
//                                }
                        }

                    }
                })
        }
    }


}
